home *** CD-ROM | disk | FTP | other *** search
- /*
- ** patch.library
- **
- ** Copyright © 1993-1997 by Stefan Fuchs
- ** Freely distributable.
- */
-
- #ifndef _PATCH_INCLUDES_H
- #include "patch_includes.h"
- #endif
-
-
- /****** patch.library/GetPatchA ***************************************
- *
- * NAME
- * GetPatchA -- Returns certain attributes of a patch. (V3)
- * GetPatch -- varargs stub for GetPatchA(). (V3)
- *
- * SYNOPSIS
- * Result = GetPatchA( patch, taglist )
- * D0 A0 A1
- *
- * ULONG Result GetPatchA( struct Patch *, struct TagItem *);
- *
- * Result = GetPatch( patch, ...)
- *
- * ULONG Result GetPatch( struct Patch *, ...);
- *
- * FUNCTION
- * Returns certain attributes and lists connected to a patch (see TAGS).
- *
- * INPUTS
- * patch = pointer to a patch structure or NULL for no action
- * taglist = pointer to array of tags
- *
- * TAGS
- * PATT_Result2 (ULONG *) - An optional pointer to a longword,
- * which will contain an errorcode as defined patch.h,
- * when the function returns.
- * Assembler programmers can get the same value from d1.
- *
- * Only one of the following tags may be specified at a time:
- *
- * PATT_PatchName (BOOL) - Return a pointer to a copy of the name of
- * the patch in a null-terminated string.
- * This pointer must be passed to PatchFreeVec(), if
- * the string is no longer needed.
- * Type of Result is STRPTR.
- * PATT_TaskListType (BOOL) - Return the type of the internal TaskList
- * Possible results:
- * TL_TYPE_INCLUDE: all specified tasks will use
- * the patchroutine, all others will ignore it.
- * TL_TYPE_EXCLUDE: all specified tasks will ignore
- * the patchroutine, all others will use it.
- * NULL: An error occurred (this includes the absence
- * of a TaskList). Check the secondary
- * errorcode for more information.
- * Type of Result is ULONG.
- * PATT_TaskList (BOOL) - Return a pointer to a taglist containing all
- * tasknames, taskids or patterns attached to a patch.
- * The tagitems are PATT_AddTaskName, PATT_AddTaskID or
- * PATT_AddTaskPattern(new for V5).
- * Unknown tags must be ignored.
- * This pointer must be passed to PatchFreeVec(), if
- * the tasklist is no longer needed.
- * Type of Result is taglist.
- * PATT_Disabled (V4) (BOOL) - Return a number representing the current
- * disable nesting counter of a patch. Null means the patch is
- * enabled and will be used, by any tasks using the
- * library function.
- * Type of Result is ULONG.
- * PATT_UserData (V5) (BOOL) - Return userdata attached to a patch.
- * Type of Result is ULONG.
- * PATT_Priority (V5) (BOOL) - Return the priority of a patch.
- * Type of Result is BYTE.
- * PATT_Original (V6) (BOOL) - Return a pointer to the original
- * function.
- * Only possible, if patch was installed with PATT_Original
- * Type of Result is (* )().
- *
- *
- * RESULT
- * Result = Pointer or longword depending on specified tags.
- *
- * Possible errorcodes returned with PATT_Result2 or in register d1:
- * PATERR_Ok
- * Indicates success of the operation.
- * PATERR_OutOfMem
- * Indicates that there was not enough memory to
- * complete the operation.
- * PATERR_InvalidHandle
- * Indicates that the pointer to the patch passed
- * to the function was not or is no longer valid.
- * This might happen, if you pass a wrong pointer or
- * you got the pointer via FindPatch() and another
- * task has removed the patch before this task called
- * RemovePatchTags().
- * PATERR_NoTaskList
- * No valid TaskList is attached to the patch.
- * The SetPatchA() function with the PATT_CreateTaskList
- * tag specified, must be called to allocate a TaskList.
- * PATERR_PatchUnnamed
- * The patch has no identification string attached
- * to it.
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * InstallPatchTags(), PatchFreeVec(), patch.h, patchtags.h
- *
- ******************************************************************************
- *
- */
-
- ULONG LIBFUNC GetPatchA( REGA0 struct Patch *patch GNUC_REGA0, REGA1 struct TagItem *taglist GNUC_REGA1)
- {
- ULONG Result1 = NULL;
- ULONG Result2;
- struct TLHeader *tasklist;
- struct Node *pointer;
- struct TagItem *ntaglist;
- ULONG *Result2ptr;
- UBYTE *memptr;
-
- Result2 = SAVEObtainSemaphore(); /* This can't be a shared semaphore, as AllocPolled() can not handle multiple tasks */
- if (Result2 == 0L)
- {
- if ((patch) && (taglist))
- {
- Result2 = TestPatchHandle(patch);
- if (Result2 == 0L)
- {
-
-
- if (GetTagData(PATT_PatchName, 0L, taglist))
- {
- if(patch->PS_Node.ln_Name)
- {
- Result1 = (ULONG)BAllocmem( strlen( patch->PS_Node.ln_Name) + 1, MEMF_CLEAR | MEMF_PUBLIC);
- if(Result1)
- {
- strcpy( (char *)Result1, patch->PS_Node.ln_Name);
- }
- else Result2 = PATERR_OutOfMem;
- }
- else Result2 = PATERR_PatchUnnamed;
- goto Ende;
- }
-
-
- if (GetTagData(PATT_TaskListType, 0L, taglist))
- {
- if( tasklist = patch->PS_PatchCode->PC_TaskList)
- Result1 = tasklist->TL_List.lh_Type;
- else
- Result2 = PATERR_NoTaskList;
- goto Ende;
- }
-
-
- if (GetTagData(PATT_TaskList, 0L, taglist))
- {
- if( tasklist = patch->PS_PatchCode->PC_TaskList)
- {
- if( Result1 = (ULONG)BAllocmem( GetNumberOfNodes((struct List *)tasklist) * 8 + 4, MEMF_CLEAR))
- {
- ntaglist = (struct TagItem *)Result1;
- for (pointer = (struct Node *)tasklist->TL_List.lh_Head;
- pointer->ln_Succ;
- pointer = (struct Node *)pointer->ln_Succ)
- {
- switch(pointer->ln_Type)
- {
- case TLI_TYPE_TASKNAME:
- ntaglist->ti_Tag = PATT_AddTaskName;
- ntaglist->ti_Data = (ULONG)pointer->ln_Name;
- ntaglist++;
- break;
- case TLI_TYPE_TASKID:
- ntaglist->ti_Tag = PATT_AddTaskID;
- ntaglist->ti_Data = (ULONG)pointer->ln_Name;
- ntaglist++;
- break;
- case TLI_TYPE_TASKPATTERN:
- ntaglist->ti_Tag = PATT_AddTaskPattern;
- ntaglist->ti_Data = (ULONG)pointer->ln_Name;
- ntaglist++;
- break;
- }
- }
- ntaglist->ti_Tag = TAG_DONE;
- }
- else
- Result2 = PATERR_OutOfMem;
- }
- else
- Result2 = PATERR_NoTaskList;
- goto Ende;
- }
-
-
- if (GetTagData(PATT_Disabled, 0L, taglist))
- {
- Result1 = patch->PS_PatchCode->PC_Disable;
- goto Ende;
- }
-
-
- if (GetTagData(PATT_ProjectID, 0L, taglist))
- {
- if (patch->PS_ProjectNode.mln_Succ)
- {
- Result1 = (ULONG)GetListNodeHeader((struct Node *)&(patch->PS_ProjectNode));
- Result1 -= offsetof(struct PatchProject, PPR_PatchListHeader);
- }
- goto Ende;
- }
-
-
- if (GetTagData(PATT_UserData, 0L, taglist))
- {
- Result1 = patch->PS_UserData;
- goto Ende;
- }
-
-
- if (GetTagData(PATT_Priority, 0L, taglist))
- {
- Result1 = patch->PS_Node.ln_Pri;
- goto Ende;
- }
-
-
- /* Note PATT_Original is currently same as PATT_SYSTEM */
- /* So PATT_SYSTEM may go away, if PatchSetFunc requires version v6 */
- if (GetTagData(PATT_Original, 0L, taglist))
- {
- Result1 = (ULONG)patch->PS_SystemEntry;
- goto Ende;
- }
-
-
- /*** PRIVATE Tags follow here ***/
-
- if (GetTagData(PATT_NewCode, 0L, taglist))
- {
- memptr = patch->PS_Jsr;
- memptr += 2;
- Result1 = (ULONG)(*((ULONG *)memptr));
- goto Ende;
- }
-
-
- if (GetTagData(PATT_SYSTEM, 0L, taglist))
- {
- Result1 = (ULONG)patch->PS_SystemEntry;
- goto Ende;
- }
-
- }
- }
- Ende:
- ReleaseSemaphore(&(PatchBase->PB_Semaphore));
- }
-
- if (Result2ptr = (ULONG *)GetTagData(PATT_Result2, 0L, taglist))
- *Result2ptr = Result2;
-
- ReturnD1(Result2);
- return(Result1);
- }
-